#ifndef RELAY_DRIVER_GLOBALS
#define RELAY_DRIVER_GLOBALS
#include <includes.h>

static void GPIO_RelayOutCfg(void);
static void POR_OutputsSta(void);
static void RCC_RelayOutCfg(FunctionalState NewState);

/**
 * @brief  Configures RCC clock for Outputs
 * @param  None
 * @retval None
 */
static void RCC_RelayOutCfg(FunctionalState NewState)
{
  uint8_t i;
  uint32_t RCC_APBxPeriph_GPIOx = 0;

  /* Enable RCC clocks */
  for (i = 0; i < RelayOutputsTOTNum; i++)
    RCC_APBxPeriph_GPIOx |= RelayOutCfgTable[i].RCC_APB2Periph;

  RCC_EnableAPB2PeriphClk(RCC_APBxPeriph_GPIOx, NewState);
}

/**
 * @brief  Configures Outputs Control lines.
 * @param  None
 * @retval None
 */
static void GPIO_RelayOutCfg(void)
{
  GPIO_InitType GPIO_InitStructure;
  uint8_t i;

  /* Configuration Port for InputsExti pin */
  for (i = 0; i < RelayOutputsTOTNum; i++)
  {
    GPIO_InitStructure.Pin = RelayOutCfgTable[i].GPIO_Pin;
    GPIO_InitStructure.GPIO_Speed = RelayOutCfgTable[i].GPIO_Speed;
    GPIO_InitStructure.GPIO_Mode = RelayOutCfgTable[i].GPIO_Mode;
    GPIO_InitPeripheral(RelayOutCfgTable[i].GPIOx, &GPIO_InitStructure);
  }
}

/**
 * @brief  Outputs Sta After POR.
 * @param  None
 * @retval None
 */
static void POR_OutputsSta(void)
{
  // 设置引脚为高电平
  for (uint8_t i = 0; i < RelayOutputsTOTNum; i++)
    GPIO_SetBits(RelayOutCfgTable[i].GPIOx, RelayOutCfgTable[i].GPIO_Pin);
}

/* Initial Outputs Config */
void RelayOutCfg_Init(void)
{
  /* Configure RCC clock */
  RCC_RelayOutCfg(ENABLE);

  /* Configure GPIO */
  GPIO_RelayOutCfg();

  /* POR status */
  POR_OutputsSta();
}
#define PhysicSTOP   0 //物理停止
#define PhysicFEV    1 //物理反转
#define PhysicFOR    2 //物理正转
/**
 * @brief 物理驱动
 * 
 *电机        动作        GPIO-电平  
 *建压        motorFOR   FORWARD-高 REVERSE-低
 *建压        motorREV   FORWARD-低 REVERSE-低
 *建压        motorStop  FORWARD-低 REVERSE-高
 *励磁分压    motorFOR   FORWARD-高 REVERSE-低
 *励磁分压    motorREV   FORWARD-低 REVERSE-低
 *励磁分流    motorFOR   FORWARD-低 REVERSE-低 （正反转调换）
 *励磁分流    motorREV   FORWARD-高 REVERSE-低
 * @param PhysicTrun 
 * @param RelayOutput_GpioFor 
 * @param RelayOutput_GpioRev 
 */
static void MotorPhysicDrive(uint8_t PhysicTrun,uint8_t RelayOutput_GpioFor,uint8_t RelayOutput_GpioRev)
{
  if(PhysicTrun==PhysicFOR)
  {
    	ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,ShareBuffer_Outputs,RelayOutput_GpioFor,BitOperaOpt_Clr);//逻辑清除==高电平
    	ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,ShareBuffer_Outputs,RelayOutput_GpioRev,BitOperaOpt_Set);//逻辑输出==低电平
  }
  else if(PhysicTrun==PhysicFEV)
  {
    	ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,ShareBuffer_Outputs,RelayOutput_GpioFor,BitOperaOpt_Set);
    	ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,ShareBuffer_Outputs,RelayOutput_GpioRev,BitOperaOpt_Set);
  }
  else
  {
    	ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,ShareBuffer_Outputs,RelayOutput_GpioFor,BitOperaOpt_Set);
    	ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,ShareBuffer_Outputs,RelayOutput_GpioRev,BitOperaOpt_Clr);
  }
}
/**
 * @brief 电机输出
 * 
 * @param motor 
 * @param normal 
 */
void motorTurn(MOTORTYPE motor,MotorAction normal)
{
  switch (motor)
  {
  case BUILDVOL_MOTOR:
    switch (normal)
    {
    case motorFOR:
      MotorPhysicDrive(PhysicFOR,RelayOutput_BUILD_VOL_FORWARD,RelayOutput_BUILD_VOL_REVERSE);
      break;
    case motorREV:
      MotorPhysicDrive(PhysicFEV,RelayOutput_BUILD_VOL_FORWARD,RelayOutput_BUILD_VOL_REVERSE);
      break;
    default:
      MotorPhysicDrive(PhysicSTOP,RelayOutput_BUILD_VOL_FORWARD,RelayOutput_BUILD_VOL_REVERSE);
      break;
    }
    break;
  case EXCI_MOTOR://与其他逻辑相反
    switch (normal)
    {
    case motorFOR:
      MotorPhysicDrive(PhysicFEV,RelayOutput_EXCI_FORWARD,RelayOutput_EXCI_REVESRE);
      break;
    case motorREV:
      MotorPhysicDrive(PhysicFOR,RelayOutput_EXCI_FORWARD,RelayOutput_EXCI_REVESRE);
      break;
    default:
      MotorPhysicDrive(PhysicSTOP,RelayOutput_EXCI_FORWARD,RelayOutput_EXCI_REVESRE);
      break;
    }
    break;
  case EXCI2_MOTOR://与其他逻辑相反
    switch (normal)
    {
    case motorFOR:
      MotorPhysicDrive(PhysicFEV,RelayOutput_EXCI2_FORWARD,RelayOutput_EXCI2_REVESRE);
      break;
    case motorREV:
      MotorPhysicDrive(PhysicFOR,RelayOutput_EXCI2_FORWARD,RelayOutput_EXCI2_REVESRE);
      break;
    default:
      MotorPhysicDrive(PhysicSTOP,RelayOutput_EXCI2_FORWARD,RelayOutput_EXCI2_REVESRE);
      break;
    }
    break;
  case EXCV_MOTOR:
    switch (normal)
    {
    case motorFOR:
      MotorPhysicDrive(PhysicFOR,RelayOutput_EXCV_FORWARD,RelayOutput_EXCV_REVESRE);
      break;
    case motorREV:
      MotorPhysicDrive(PhysicFEV,RelayOutput_EXCV_FORWARD,RelayOutput_EXCV_REVESRE);
      break;
    default:
      MotorPhysicDrive(PhysicSTOP,RelayOutput_EXCV_FORWARD,RelayOutput_EXCV_REVESRE);
      break;
    }
    break;
  case EXCV2_MOTOR:
    switch (normal)
    {
    case motorFOR:
      MotorPhysicDrive(PhysicFOR,RelayOutput_EXCV2_FORWARD,RelayOutput_EXCV2_REVESRE);
      break;
    case motorREV:
      MotorPhysicDrive(PhysicFEV,RelayOutput_EXCV2_FORWARD,RelayOutput_EXCV2_REVESRE);
      break;
    default:
      MotorPhysicDrive(PhysicSTOP,RelayOutput_EXCV2_FORWARD,RelayOutput_EXCV2_REVESRE);
      break;
    }
    break;
  }
}

#endif